﻿using Ionic.Zip;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using NLog;
using Simple.FileBackClient.Entity;
using Simple.Framework;
using Simple.Framework.Configuration;
using Simple.Framework.Schedule;
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Xml;

namespace Simple.PrettyClient
{
	internal class BackupsSchedule : ISchedule
	{
		Socket socket;
		ILogger logger;
		IClientConfiguration configuration;
		int connectCount = 0;
		int successCount = 0;
		FileDto fileDto;
		public BackupsSchedule(IClientConfiguration configuration,ILogger logger) {
			this.logger= logger;
			this.configuration= configuration;
			fileDto = new FileDto();
			ScheduleInfo = new ScheduleInfo();
			Schedule schedule = configuration.Schedules[0];
			ScheduleInfo.Title = "备份文件的服务!";
			TimeSpan now = DateTime.Now.TimeOfDay;
			if (schedule.BackupsTime.Ticks>=now.Ticks)
			{
				ScheduleInfo.BeforeStartWait = 0;//schedule.BackupsTime.Ticks - now.Ticks;
			}
			else
			{
				ScheduleInfo.BeforeStartWait = 0;//now.Ticks-schedule.BackupsTime.Ticks+TimeSpan.TicksPerDay;
			}
			ScheduleInfo.Period = schedule.Cycle * TimeSpan.TicksPerSecond;

			ConnectServce();
		}
		public ScheduleInfo ScheduleInfo { get; set; }

		public void Run()
		{
			if (!IsSuccess())
			{
				ConnectServce();
			}

			foreach (var dir in configuration.BackupsDirectorys)
			{
				Direc(dir);

				using (FileStream fs=new FileStream($"{fileDto.ClientDir}\\{fileDto.FileName}{fileDto.Ext}", FileMode.Open,FileAccess.Read))
				{
					int bufferLenght = 1024 * 1024;
					byte[] buffer = new byte[bufferLenght];
					int length =1;
					long l = fs.Length;
					for (int i = 0; length != 0; i++)
					{
					       length = fs.Read(buffer,2,bufferLenght-2);
					}
					
				}
			}
            // Console.WriteLine(DateTime.Now.ToShortDateString());
        }

		public void ConnectServce()
		{
			try
			{
				Create();
				Connect();
			}
			catch (Exception ex)
			{
				logger.Error(ex.Message);
				logger.Error(ex.StackTrace);
				logger.Error("已经接{}次!");
			}
		}

		public bool IsSuccess()
		{
			return socket.Connected;
		}

		public void Create()
		{
			if (socket == null)
			{
				socket = new Socket(SocketType.Stream, ProtocolType.Tcp);
			}
		}

		public void Connect()
		{

			socket.Connect(configuration.ToIPAddress, configuration.ToPort);
			if (IsSuccess())
			{
				logger.Info($"成功链接{configuration.ToIPAddress} {configuration.ToPort}!");
			}
		}

		public void Direc(string Dir)
		{
			fileDto.RootDir = Path.GetDirectoryName(Dir);
			fileDto.FileName = Path.GetFileName(Dir);
			fileDto.ClientDir= Dir;
			fileDto.Ext= ".zip";
			fileDto.Realation = "\\dir\\dir";
			//Compress(fileDto.ClientDir, fileDto.FileName+".zip");
			var strdata=JsonConvert.SerializeObject(fileDto);
			byte[] bytes=Encoding.UTF8.GetBytes(strdata);
			byte[]bs=new byte[4];
			Send(16,bytes);
		}
		//
		#region 1,开始传文件的准备
		//hash
		//根目录名称		//服务器端有一个根目录，在根目录下面再创建改目录名称
		//文件名称		   
		//客户端路径		//相对路径
		//
		#endregion

		public static bool Compress(string directory, string strZipName, bool isDirStruct = false)
		{
			if (directory == null)
			{
				throw new ArgumentNullException("list");
			}
			if (!Directory.Exists(directory))
			{
				return false;
			}
			if (string.IsNullOrEmpty(strZipName))
			{
				throw new ArgumentNullException(strZipName);
			}
			try
			{
				//设置编码，解决压缩文件时中文乱码
				using (var zip = new ZipFile(Encoding.UTF8))
				{
					zip.UseZip64WhenSaving = Zip64Option.AsNecessary;//or Uncompressed size, or offset exceeds the maximum value.Consider setting the UseZip64WhenSaving property on the ZipFile instance.
					if (isDirStruct)
					{
						foreach (var path in Directory.GetDirectories(directory))
						{
							var fileName = Path.GetFileName(path);
							zip.AddDirectory(path, fileName);
						}

						foreach (var path in Directory.GetFiles(directory))
						{
							zip.AddFile(path, "");
						}
					}
					else
					{
						zip.AddDirectory(directory);
					}

					zip.Save($"{directory}\\{strZipName}");
					return true;
				}
			}
			catch (Exception ex)
			{
				throw new Exception(ex.Message);
			}
		}

		public void Send(int cmd,byte[] bytes)
		{
			ArrayBufferWriter<byte> output = new System.Buffers.ArrayBufferWriter<byte>();

			int len = 4 + bytes.Length;
			var span = output.GetSpan(len);

			int offset = 0;
			//1.长度
			//命令
			//
			XBuffer.WriteInt(len, span,ref offset);
			XBuffer.WriteInt(cmd,span,ref offset);
			XBuffer.WriteBytesWithoutLength(bytes, span, ref offset);
			output.Advance(len);
			var result=output.WrittenSpan.ToArray();
		}
	}
}
